<?php

/**
 * Description of Login
 *
 * @author lmcosta
 */
class Login {
    
    var $max_tamanho_user;
    var $max_tamanho_pass;
    
    //Log de erros
    var $msg_erro;  

    function __construct() {
        //Dados por defeito
        $this->max_tamanho_user = 15;
        $this->max_tamanho_pass = 15;
    }
    
    function logout() {
        if (!isset($_SESSION)) {
            session_start();
        }
        session_destroy();
    }

    /**
     * Validar login introduzido no formulário
     * @return boolean 
     */
    function validaLogin() {
        
        //Validar se a csrf_token é igual à que foi gerada quando foi apresentado o formulário
        $csrf_token = $_POST['csrf_token'];
        if ($csrf_token != $_SESSION['csrf_token']) {
            $this->defineErro("Iniciar de novo o formulário!");
            return false;
        }
        
        //obter username e password do formulário e retirar espaços
        $username = trim($_POST['username']);
        $password = trim($_POST['password']);
              
        //Validar campos
        if (empty($username)) {
            $_POST['username'] = $username;
            $this->defineErro("Utilizador vazio!");
            return false;
        }

        if (empty($_POST['password'])) {
            $this->defineErro("Password vazia!");
            return false;
        }
        
        if(!FormHelper::validateMaxTamanho($username, $this->max_tamanho_user)) {
            $this->defineErro("O username está limitado a " . $this->max_tamanho_user . " caracteres!");
            return false;
        }
        
        if(!FormHelper::validateMaxTamanho($password, $this->max_tamanho_pass)) {
            $this->defineErro("A password está limitada a " . $this->max_tamanho_pass . " caracteres!");
            return false;
        }

        //Encriptar password
        $password = FormHelper::encriptarPassword($password);
        
        //Validar na base de dados
        $loginDB = new LoginDB();
        $userdata = null;
        if (!$loginDB->validaLogin($username, $password, $userdata)) {
            $this->defineErro($loginDB->msg_erro);
            return false;
        }
        
        //Gerar id de sessão
        $session = FormHelper::gerarIDSessao();
        
        //Guardar sessão
        $userdata['session'] = $session;
        $userdata['timestamp'] = time(); //instante de tempo em que efectuou o login
        $_SESSION['userdata'] = $userdata;

        return true;
    }

    /**
     * Validar se o utilizador está ligado
     * Condições:
     *  - A sessão tem de existir
     *  - O id da sessão armazenado tem de ser igual ao id gerado
     *  - A duração da sessão nao pode exceder o valor definido como session timeout
     * @return boolean 
     */
    function utilizadorLigado() {
        $site = Site::getInstance();
        //Gerar id de sessão actual para verificar se corresponde à que está armazenada na sessão
        $session = FormHelper::gerarIDSessao();
        
        if (!isset($_SESSION['userdata'])) {
            return false;
        } elseif (!isset($_SESSION['userdata']['session']) || ($_SESSION['userdata']['session'] != $session)) {
            session_destroy();
            return false;
        } elseif (( time() - $_SESSION['userdata']['timestamp']) > $site->sessionTimeout ) {
            session_destroy();
            return false;
        }
        
        return true;
    }

    function defineErro($erro) {
        $this->msg_erro .= $erro . "\r\n";
    }

}

/**
 * Classe que é o modelo do login na base de dados. 
 */
class LoginDB {
    
    var $db_table;
    var $msg_erro;
    
    function __construct() {
        //Dados por defeito
        $this->db_table = "utilizadores";
        $this->msg_erro = "";
    }
    
    /**
     * Validar um username na base de dados
     * Se o utilizador existir, userdata vai ser inicializado para ser guardado na sessão
     * @param type $username
     * @param type $password
     * @param type $userdata
     * @return boolean 
     */
    function validaLogin($username, $password, &$userdata) {
        $site = Site::getInstance();
        if (!$site->ligarDB($this->msg_erro)) {
            return false;
        }
        
        //Manter segurança do valor do username para não causar sql injection
        $username = FormHelper::tranformarToQuery($username);
        
        $sql = "SELECT * FROM `$this->db_table` WHERE `username` = '$username' AND `password` = '$password' LIMIT 1 ";
        $result = mysql_query($sql, $site->ligacao_db);
        if (!$result || mysql_num_rows($result) <= 0) {
            $this->msg_erro = "Dados de login inválidos!";
            return false;
        }
        
        $user = mysql_fetch_object( $result );
        
        //Construir array para guardar na sessão
        $userdata = array(
            'id' => $user->id,
            'username' => $user->username,
        );
        
        mysql_free_result($result);
        $site->closeDB();
        
        return true;
    }

}
?>